﻿package  com.pool.core
{
	import com.pool.events.GameEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import com.pool.Config;
	import flash.media.Sound;
	import org.dm.math.geom.Line2;
	/**
	 * ...
	 * @author Scott
	 */
	public class Balls extends Sprite
	{
		private var _balls:Array;		//所有的球
		private var _ballOn:Array;		//在台上的球
		private var _len:Number;		//球的个数
		private var _girth:Number = 31;		//材质长=球的周长
		private var _center:Point;		//球台中心，也就是光照点
		private var _maxW:Number;		//球台内沿宽
		private var _maxH:Number;		//球台内沿高
		private var _holes:Array;		//球洞
		
		private var _r:Number = 12.5;
		
		private var _texture:Array;
		public var power:Number = 0;
		public var angle:Number = 0;
		
		private var i:int;
		private var j:int;
		private var w:int;
		private var p1:Shape;
		private var p2:Shape;
		
		public function Balls(pooltype:uint) 
		{
			_balls = new Array();
			_ballOn = new Array();
			init();
		}
		
		public function render():void 
		{
			this.addEventListener(Event.ENTER_FRAME, updata);
		}
		
		public function stop():void
		{
			this.removeEventListener(Event.ENTER_FRAME, updata);
			for (i = 0; i < 16; i++)
			{
				_balls[i].reSet();
			}
		}
		
		public function get whiteBall():Ball 
		{
			return _balls[0]; 
		}
		
		public function updata(e:Event):void 
		{
			_rootonEnterFrame();
		}
		
		private function init():void 
		{
			_holes = new Array();
			_holes.push(new Rectangle(-15, -15, 35, 35));
			_holes.push(new Rectangle(338, -20, 40, 30));
			_holes.push(new Rectangle(702, -15, 30, 30));
			_holes.push(new Rectangle(-15, 341, 30, 30));
			_holes.push(new Rectangle(338, 346, 40, 30));
			_holes.push(new Rectangle(702, 341, 30, 30));
			
			initBalls();
			
			//this.graphics.beginFill(0x0000FF, .5);
			//for (i = 0; i < 6;i++)
			//{
				//this.graphics.drawRect(_holes[i].x, _holes[i].y, _holes[i].width, _holes[i].height);
			//}
			p1 = new Shape();
			p2 = new Shape();
		}
		
		public function initBalls():void 
		{
			i = -1;
			var rect:Rectangle = new Rectangle(0, 0, 128, 128);
			_balls.push(new Ball(0));
			var q00:Point = new Point(0, 0);
			var q10:Point = new Point(128, 0);
			var q01:Point = new Point(0, 128);
			var q11:Point = new Point(128, 128);
			while (++i < 15)
			{
				var imgBuf:BitmapData = new BitmapData(256, 256);
				imgBuf.copyPixels(new _texture[i](0,0), rect, q00);
				imgBuf.copyPixels(new _texture[i](0,0), rect, q10);
				imgBuf.copyPixels(new _texture[i](0,0), rect, q01);
				imgBuf.copyPixels(new _texture[i](0, 0), rect, q11);
				_balls.push(new Ball(i+1,imgBuf));
			}
			var t:Ball = _balls[2];
			_balls[2] = _balls[15];
			_balls[15] = t;
			t = _balls[5];
			_balls[5] = _balls[8];
			_balls[8] = t;
			t = _balls[6];
			_balls[6] = _balls[11];
			_balls[11] = t;
			t = _balls[7];
			_balls[7] = _balls[10];
			_balls[10] = t;
			_len = _balls.length;
		}
		//
		public function reSet():void 
		{
			_balls[0].setPos(163, 178);
			_balls[1].setPos(530, 178);
			_balls[2].setPos(552, 165);
			_balls[3].setPos(552, 191);
			_balls[4].setPos(575, 152);
			_balls[5].setPos(575, 178);
			_balls[6].setPos(575, 204);
			_balls[7].setPos(597, 139);
			_balls[8].setPos(597, 165);
			_balls[9].setPos(597, 191);
			_balls[10].setPos(597, 217);
			_balls[11].setPos(619, 126);
			_balls[12].setPos(619, 152);
			_balls[13].setPos(619, 178);
			_balls[14].setPos(619, 204);
			_balls[15].setPos(619, 229);
			
			i = -1;
			while (++i < _len)
			{
				_ballOn[i] = _balls[i];
				_ballOn[i].isOn = true;
				if (!this.contains(_balls[i])) this.addChild(_balls[i]);
			}
		}
		
		public function isStopAll():Boolean
		{
			i = -1;
			while (++i < 16)
			{
				if(_balls[i].isMove()) return false;
			}
			return true;
		}
		
		public function isCanBall():Boolean 
		{			
			for (i = 1; i < 16; i++)
			{
				if (_balls[i].isOn) 
				{
					if ((_balls[0].x - _balls[i].x) * (_balls[0].x - _balls[i].x) + (_balls[0].y - _balls[i].y) * (_balls[0].y - _balls[i].y) < 625)
					{
						return false;
					}
				}
			}
			return true;
		}
		
		public function onShot():void
		{
			var sY:Number = power * Math.sin(angle);
			var sX:Number = power * Math.cos(angle);
			whiteBall.vpx = sX;
			whiteBall.vpy = sY;
		}
		
		public function reSetWhite():void 
		{
			_balls[0].setPos(163, 178);
			_balls[0].reSet();
		}
		
		private function hitTest(a:Ball, b:Ball):Array
		{
			//dispatchEvent(new GameEvent(GameEvent.HIT));
			
			var e:Number = .98;
			var e1:Number = .98;
			var e2:Number = .95;
			
			var vIgnore:Number = .2;
			var _loc3:Number = b.px - a.px;
			var _loc2:Number = b.py - a.py;
			var _loc9:Number = Math.sqrt(_loc3 * _loc3 + _loc2 * _loc2);
			_loc3 = _loc3 / _loc9;
			_loc2 = _loc2 / _loc9;
			var _loc7:Number = -_loc2;
			var _loc6:Number = _loc3;
			var _loc8:Number = a.vpx * _loc3 + a.vpy * _loc2;
			var _loc14:Number = a.vpx * _loc7 + a.vpy * _loc6;
			if (_loc8 < 0)
			{
				if (Math.abs(_loc8) > vIgnore)
				{
					a.px = a.px - a.vpx;
					a.py = a.py - a.vpy;
					b.px = b.px - b.vpx;
					b.py = b.py - b.vpy;
					_loc3 = b.px - a.px;
					_loc2 = b.py - a.py;
					_loc9 = Math.sqrt(_loc3 * _loc3 + _loc2 * _loc2);
					_loc3 = _loc3 / _loc9;
					_loc2 = _loc2 / _loc9;
					_loc7 = -_loc2;
					_loc6 = _loc3;
					_loc8 = a.vpx * _loc3 + a.vpy * _loc2;
					_loc14 = a.vpx * _loc7 + a.vpy * _loc6;
				}
				else
				{
					_loc8 = 0;
				} // end if
			} // end else if
			var _loc10:Number = b.vpx * _loc3 + b.vpy * _loc2;
			var _loc16:Number = b.vpx * _loc7 + b.vpy * _loc6;
			if (Math.abs(_loc10) < vIgnore)
			{
				_loc10 = 0;
			} // end if
			var _loc12:Number = ((e + 1) * _loc10 + _loc8 * (1 - e)) / 2;
			var _loc15:Number = _loc14;
			var _loc13:Number = ((e + 1) * _loc8 - _loc10 * (1 - e)) / 2;
			var _loc11:Number = _loc16;
			var _loc4:Array = new Array(4);
			_loc4[0] = _loc3 * _loc12 + _loc7 * _loc15;
			_loc4[1] = _loc2 * _loc12 + _loc6 * _loc15;
			if (Math.abs(_loc4[0]) < vIgnore)
			{
				_loc4[0] = 0;
			} // end if
			if (Math.abs(_loc4[1]) < vIgnore)
			{
				_loc4[1] = 0;
			} // end if
			_loc4[2] = _loc3 * _loc13 + _loc7 * _loc11;
			_loc4[3] = _loc2 * _loc13 + _loc6 * _loc11;
			if (Math.abs(_loc4[2]) < vIgnore)
			{
				_loc4[2] = 0;
			} // end if
			if (Math.abs(_loc4[3]) < vIgnore)
			{
				_loc4[3] = 0;
			} // end if
			return (_loc4);
		}
		
		public function _rootonEnterFrame():void
		{
			var n:Array;
			var xa:Number;
			var ya:Number;
			var d1:Number;
			var d2:Number;
			var d3:Number;
			for (i = 0; i < 16;i++ )
			{
				var ib:Ball = _balls[i];
				if (!ib.isOn) continue;
				var ix:Number = ib.px;
				var iy:Number = ib.py;
				for (j = i+1; j < 16;j++ )
				{
					var jb:Ball = _balls[j];
					if (!jb.isOn) continue;
					xa = jb.px + jb.vpx - (ib.px + ib.vpx);
					ya = jb.py + jb.vpy - (ib.py + ib.vpy);
					d1 = xa * xa + ya * ya;
					//xa = jb.px - (ib.px + ib.vpx);
					//ya = jb.py - (ib.py + ib.vpy);
					//d2 = xa * xa + ya * ya;
					//xa = jb.px + jb.vpx - ib.px;
					//ya = jb.py + jb.vpy - ib.py;
					//d3 = xa * xa + ya * ya;|| d2 < 625 || d3 < 625
					//d = Line2.DistanceLine(ib.px, ib.py, ib.px + ib.vpx, ib.py + ib.vpy, jb.px + jb.vpy, jb.py + jb.vpy);
					if(d1<610) dispatchEvent(new GameEvent(GameEvent.HIT));
					if (d1 <= 625 )
					{
						n = hitTest(_balls[i], _balls[j]);
						ib.vpx = n[0];
						ib.vpy = n[1];
						ib.vax = -n[0]*3;
						ib.vay = -n[1]*3;
						//ib.vay = n[1]<0?-n[1]*3:n[1]*3;
						//ib.vay = n[1]<0?-n[1]*3:n[1]*3;
						jb.vpx = n[2];
						jb.vpy = n[3];
						jb.vax = -n[2]*3;
						jb.vay = -n[3]*3;
						//jb.vax = n[2]<0?-n[2]*3:n[2]*3;
						//jb.vay = n[3]<0?-n[3]*3:n[3]*3;
					}
					
				}
				for (w = 0; w < 6; w++)
				{
					if (ix + ib.vpx >= _holes[w].x && ix + ib.vpx <= _holes[w].x+_holes[w].width && iy + ib.vpy >= _holes[w].y && iy + ib.vpy <= _holes[w].y+_holes[w].height)
					{
						ib.reSet();
						ib.isOn = false;
						ib.visible = false;
						//if (ib.num == 0)
						//{
							//ib.isOn = true;
							//ib.visible = true;
							//reSetWhite();
						//}
						continue;
					}
				} // end while
				if (!ib.isOn) continue;
				if (ib.px >= Config.deskW-_r && ib.vpx > 0 || ib.px <= _r && ib.vpx < 0)
				{
					ib.vpx = -Config.bd_MoveXDec * ib.vpx;
				}
				else if (ib.py >= Config.deskH-_r && ib.vpy > 0 || ib.py <= _r && ib.vpy < 0)
				{
					ib.vpy = -Config.bd_MoveYDec * ib.vpy;
				}
			}
			
			for (i = 0; i < 16;i++)
			{
				if (!_balls[i].isOn) continue;
				_balls[i].move();
			}
			
			if (this.isStopAll()) 
			{
				this.stop();
				dispatchEvent(new GameEvent(GameEvent.STOPALL));
			}
		}
	}
}